package pl.com.qapps.datastore.berkeley.impl;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import pl.com.qapps.datastore.EntityStore;
import pl.com.qapps.datastore.IdStore;
import pl.com.qapps.datastore.KindIndex;
import pl.com.qapps.datastore.MultiPropertyStore;
import pl.com.qapps.datastore.SinglePropertyStore;
import pl.com.qapps.datastore.Store;
import pl.com.qapps.datastore.TransactionCore;

import com.google.appengine.api.datastore.Transaction;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;

/**
 * 
 * @author Jakub Dykowski
 * 
 */
public class BerkeleyStore extends Store {

	private static final String ENTITY_DB = "entities.db";
	private static final String KIND_DB = "kind.db";
	private static final String CLASS_DB = "classes.db";
	private static final String ID_DB = "id.db";
	private static final String ASC_DB = "asc.db";
	private static final String DESC_DB = "desc.db";

	private final Environment env;
	private final StoreTable classes;
	private final BerkeleyIdStore ids;
	private final BerkeleyEntityStore entities;
	private final BerkeleyKindIndex kind;
	private final BerkeleyIndexStore ascendingIndex;
	private final BerkeleyIndexStore descendingIndex;

	public BerkeleyStore(File directory) {
		env = new Environment(directory, new EnvironmentConfig()
				.setAllowCreate(true).setTransactional(true)
				.setLockTimeout(10000, TimeUnit.MILLISECONDS));

		classes = new ClassesStore(env, CLASS_DB);
		ids = new BerkeleyIdStore(env, ID_DB);
		entities = new BerkeleyEntityStore(env, ENTITY_DB);
		kind = new BerkeleyKindIndex(env, KIND_DB, entities.getDatabase());
		ascendingIndex = new BerkeleyIndexStore(env, ASC_DB,
				entities.getDatabase(), false);
		descendingIndex = new BerkeleyIndexStore(env, DESC_DB,
				entities.getDatabase(), true);

	}

	@Override
	public void close() throws IOException {
		// closing DBs in reverted order
		descendingIndex.close();
		ascendingIndex.close();
		kind.close();
		entities.close();
		ids.close();
		classes.close();

		env.close();
	}

	@Override
	public EntityStore getEntityStore() {
		return entities;
	}

	@Override
	public IdStore getIdStore() {
		return ids;
	}

	@Override
	public KindIndex getKindIndex() {
		return kind;
	}

	@Override
	public SinglePropertyStore getAscendingPropertyStore() {
		return ascendingIndex;
	}

	@Override
	public SinglePropertyStore getDescendingPropertyStore() {
		return descendingIndex;
	}

	@Override
	public MultiPropertyStore getMultiPropertyStore() {
		// TODO implement
		throw new UnsupportedOperationException("not supported yet");
	}

	@Override
	public TransactionCore getTransactionCore() {
		return new BerkeleyTransactionCore(env);
	}

}
